package ${msgRegisterPackage};


import com.google.protobuf.GeneratedMessageV3;
<#list allMsgPackage as msgPackage>
import ${msgPackage};
</#list>


import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;

public class MsgManager {
    private enum Single {
        /**
         * 单例对象的实例
         */
        INSTANCE;
        private MsgManager msgManager;

        Single() {
            this.msgManager = new MsgManager();
        }
    }

    public static MsgManager getInstance() {
        return Single.INSTANCE.msgManager;
    }

    private final ConcurrentHashMap${"<Integer, Class<? extends GeneratedMessageV3>>"?string} msgRegisters = new ConcurrentHashMap();
    private final ConcurrentHashMap${"<Class<? extends GeneratedMessageV3>,Integer>"?string} msgMapId = new ConcurrentHashMap();
    private final ConcurrentHashMap${"<Class<? extends GeneratedMessageV3>, Method>"?string} methodCache = new ConcurrentHashMap();

    private MsgManager() {
        registerMsgs();
        cacheMethod();
    }

    /**
     * 缓存消息类型解析数据的方法
     */
    private void cacheMethod() {
        msgRegisters.values().forEach((clazz) -> {
            try {
                Method method = clazz.getMethod("parseFrom", byte[].class);
                method.setAccessible(true);
                methodCache.put(clazz, method);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 注册消息类型
     */
    private void registerMsgs() {
        <#list msgDefinitions as def>
            msgRegisters.put(${def.msgId?c}, ${def.msgClassName});
<#--            msgMapId.put(Move.C2S_SyncPosition.class,1 );-->
            msgMapId.put(${def.msgClassName},${def.msgId?c});
        </#list>
    }

    public Class${"<? extends GeneratedMessageV3>"?string} getMsgClass(Integer msgId) {
        return msgRegisters.get(msgId);
    }


    public Method getMethod(${"Class<? extends GeneratedMessageV3>"?string} clazz) {
        return methodCache.get(clazz);
    }

    public Integer getMsgId(${"Class<? extends GeneratedMessageV3>"?string} clazz) {
        return msgMapId.get(clazz);
    }

}
